#!/usr/bin/env python
# -- encoding utf-8 --
#
#  Created by Skiloop
#  Email: skiloop@126.com
#
import codecs
import os
import subprocess
import tempfile
import cv2
from PIL import Image


def _run_command(command):
    """
    run system command
    :param command: command
    :return: command output results
    """
    proc = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    errors = proc.stdout.read().strip()
    return (proc.wait(), errors)


def run_tesseract(input_file, output_file, lang=None, options=None, config=None, tesseract='tesseract'):
    """
    run tesseract
    :param image: image object
    :param lang: language
    :param options: other options
    :param config: configure file
    :param tesseract: tesseract command
    :return:
    """
    if tesseract is None:
        tesseract = 'tesseract'

    command = [tesseract, input_file, output_file]
    if lang is not None:
        command += ['-l', lang]
    if options is not None:
        if isinstance(options, str):
            command += [options]
        elif isinstance(options, list):
            command += options
    if config is not None:
        command += [config]
    ret, errors = _run_command(command)
    if ret:
        raise Exception(errors)
    output_file_name = output_file + '.txt'
    if os.access(output_file_name, os.R_OK):
        try:
            out = codecs.open(output_file_name, encoding='utf-8')
            res = out.read().strip()
            out.close()
            return res
        except IOError:
            pass
        finally:
            os.remove(output_file_name)


def resolve_captcha(image, **kwargs):
    """
    resolve captcha with tesseract ocr
    :param image: instance of PIL.Image.open
    :param kwargs: tesseract parameters
    :return: resolve results
    """
    with tempfile.NamedTemporaryFile(prefix='tess', suffix='.bmp') as input_file:
        with tempfile.NamedTemporaryFile(prefix='tess') as output_file:
            output_file_base = output_file.name
        if image.mode != 'RGB':
            image = image.convert('RGB')
        image.save(input_file.name)
        return run_tesseract(input_file.name, output_file_base,
                             kwargs.get('lang'), kwargs.get('options')
                             , kwargs.get('config'), kwargs.get('tesseract'))


def binary_image(cv_image, threshold=125, maxval=255):
    """
    convert image to binary image
    :param cv_image: image by cv2.imread
    :param threshold: threshold
    :param maxval: max RGB value of image
    :return: cv2 binary image data
    """
    ret, binary = cv2.threshold(cv_image, threshold, maxval, cv2.THRESH_BINARY)
    return binary


def resolve_binary(filename, threshold, maxval=255, **kwargs):
    img = cv2.imread(filename, 0)
    bimg = binary_image(img, threshold, maxval)
    with tempfile.NamedTemporaryFile(prefix='bin', suffix='.bmp') as infile:
        func = kwargs.get('func')
        if func is not None:
            func(bimg)
        cv2.imwrite(infile.name, bimg)
        return resolve_captcha(Image.open(infile.name), **kwargs)


def remove_noise(img, threshold=100):
    height, width = img.shape
    for i in range(0, height):
        j = 0
        while j < width:
            while j < width and img[i, j] < threshold:
                img[i, j] = 255
                j += 1
            j += 1
